﻿using Koala.Pro.Common;
using Koala.Pro.Common.Extension;
using Koala.Pro.Core.Models;
using Koala.Pro.Services;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Markup;

namespace Koala.Pro.Controls
{
    public partial class FunctionControl : UserControl, IComponentConnector
    {
        private bool isInit;

        public static readonly DependencyProperty FunctionInfosProperty = DependencyProperty.Register("FunctionInfos", typeof(List<FunctionInfo>), typeof(FunctionControl));

        public static readonly DependencyProperty SelectItemProperty = DependencyProperty.Register("SelectItem", typeof(FunctionInfo), typeof(FunctionControl));

        public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(FunctionControl), new FrameworkPropertyMetadata("所属功能", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

        public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(string), typeof(FunctionControl), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnValuePropertyChanged));

        public static readonly DependencyProperty ValueChangedCommandProperty = DependencyProperty.Register("ValueChangedCommand", typeof(ICommand), typeof(FunctionControl), new PropertyMetadata((object)null));

        public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register("CommandParameter", typeof(object), typeof(FunctionControl));

        public static readonly RoutedEvent ValueChangedEvent;

        public List<FunctionInfo> FunctionInfos
        {
            get
            {
                return (List<FunctionInfo>)GetValue(FunctionInfosProperty);
            }
            set
            {
                SetValue(FunctionInfosProperty, value);
            }
        }

        public FunctionInfo SelectItem
        {
            get
            {
                return (FunctionInfo)GetValue(SelectItemProperty);
            }
            set
            {
                SetValue(SelectItemProperty, value);
            }
        }

        public string Text
        {
            get
            {
                return (string)GetValue(TextProperty);
            }
            set
            {
                SetValue(TextProperty, value);
            }
        }

        public string? Value
        {
            get
            {
                return (string)GetValue(ValueProperty);
            }
            set
            {
                SetValue(ValueProperty, value);
            }
        }

        public ICommand ValueChangedCommand
        {
            get
            {
                return (ICommand)GetValue(ValueChangedCommandProperty);
            }
            set
            {
                SetValue(ValueChangedCommandProperty, value);
            }
        }

        public object CommandParameter
        {
            get
            {
                return GetValue(CommandParameterProperty);
            }
            set
            {
                SetValue(CommandParameterProperty, value);
            }
        }

        public event RoutedEventHandler ValueChanged
        {
            add
            {
                AddHandler(ValueChangedEvent, value);
            }
            remove
            {
                RemoveHandler(ValueChangedEvent, value);
            }
        }

        public FunctionControl()
        {
            InitializeComponent();
        }

        protected override async void OnInitialized(EventArgs e)
        {
            base.OnInitialized(e);
            await Init();
        }

        public async Task Init()
        {
            if (!isInit && !this.IsInDesignMode())
            {
                string systemType = App.ViewModel.SystemType;
                new List<FunctionInfo>();
                List<FunctionInfo> list = ((!App.ViewModel.IsSuperAdmin) ? (await BLLFactory<IFunctionService>.Instance.GetFunctionNodesByUser(App.ViewModel.UserInfo.Id, systemType)) : (await BLLFactory<IFunctionService>.Instance.GetTree(systemType)));
                list.Insert(0, new FunctionInfo
                {
                    Name = "顶级目录",
                    Id = "-1"
                });
                FunctionInfos = list;
                isInit = true;
            }
        }

        private static async void OnValuePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (!(d is FunctionControl control) || control == null)
            {
                return;
            }
            string oldValue = e.OldValue?.ToString();
            string newValue = e.NewValue?.ToString();
            if (!newValue.IsNullOrEmpty())
            {
                if (!control.isInit)
                {
                    await control.Init();
                }
                List<FunctionInfo> list = control.FunctionInfos?.FindFunctionNodes((FunctionInfo s) => s.Id == newValue);
                if (list != null && list.Count > 0 && list[0] != null)
                {
                    control.SelectItem = list[0];
                }
                RoutedPropertyChangedEventArgs<string> routedPropertyChangedEventArgs = new RoutedPropertyChangedEventArgs<string>(oldValue, newValue, ValueChangedEvent);

                control.RaiseEvent(routedPropertyChangedEventArgs);
                control.ValueChangedCommand?.Execute(newValue);
            }
        }

        private void TreeComboBox_SelectedItemChanged(object sender, RoutedEventArgs e)
        {
            FunctionInfo selectItem = SelectItem;
            if (selectItem != null && Value != selectItem.Id.ToString())
            {
                Value = selectItem.Id.ToString();
            }
        }

        static FunctionControl()
        {
            ValueChangedEvent = EventManager.RegisterRoutedEvent("ValueChangedEvent", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(FunctionControl));
        }
    }

}
